#    pythonequations is a collection of equations expressed as Python classes
#    Copyright (C) 2008 James R. Phillips
#    2548 Vera Cruz Drive
#    Birmingham, AL 35235 USA
#    email: zunzun@zunzun.com
#
#    License: BSD-style (see LICENSE.txt in main source directory)
#    Version info: $Id: __init__.py 267 2010-09-25 13:25:43Z zunzun.com $

import pythonequations, pythonequations.EquationBaseClasses, pythonequations.ExtraCodeForEquationBaseClasses
import numpy
numpy.seterr(all = 'raise') # numpy raises warnings, convert to exceptions to trap them


class GaussianA3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name ="Gaussian A"
    _HTML = "z = a * exp(-0.5 * (((x-b)/c)<sup>2</sup> + ((y-d)/f)<sup>2</sup>))"
    coefficientDesignatorTuple = ("a", "b", "c", "d", 'f')
    function_cpp_code = 'temp = coeff[0] * exp(-0.5 * (pow((_id[_cwo[0]+i] - coeff[1]) / coeff[2], 2.0) + pow((_id[_cwo[1]+i] - coeff[3]) / coeff[4], 2.0)));'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Y(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a * exp(-0.5 * (pow((x_in-b)/c, 2.0) + pow((y_in-d)/f, 2.0)));\n"
        return s



class GaussianB3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name ="Gaussian B"
    _HTML = "z = a * exp(-0.5 * (((x-b)/c)<sup>2</sup>)) + d * exp(-0.5 * (((y-f)/g)<sup>2</sup>))"
    coefficientDesignatorTuple = ("a", "b", "c", "d", "f", "g")
    function_cpp_code = 'temp = coeff[0] * exp(-0.5 * (pow((_id[_cwo[0]+i] - coeff[1]) / coeff[2], 2.0))) + coeff[3] * exp(-0.5 * (pow((_id[_cwo[1]+i] - coeff[4]) / coeff[5], 2.0)));'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Y(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a * exp(-0.5 * (pow((x_in-b)/c, 2.0))) + d * exp(-0.5 * (pow((y_in-f)/g, 2.0)));\n"
        return s



class LorentzianA3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name ="Lorentzian A"
    _HTML = "z = a / ((1+((x-b)/c)<sup>2</sup>)*(1+((y-d)/f)<sup>2</sup>))"
    coefficientDesignatorTuple = ("a", "b", "c", "d", 'f')
    function_cpp_code = 'temp = coeff[0] / ((1.0 + pow((_id[_cwo[0]+i] - coeff[1]) / coeff[2], 2.0)) + (1.0 + pow((_id[_cwo[1]+i] - coeff[3]) / coeff[4], 2.0)));'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Y(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a / ((1.0 + pow((x_in-b)/c, 2.0)) * (1.0 + pow((y_in-d)/f, 2.0)));\n"
        return s



class LorentzianB3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name ="Lorentzian B"
    _HTML = "z = a / (1+((x-b)/c)<sup>2</sup>) + d * (1+((y-f)/g)<sup>2</sup>)"
    coefficientDesignatorTuple = ("a", "b", "c", "d", "f", "g")
    function_cpp_code = 'temp = coeff[0] / (1.0 + pow((_id[_cwo[0]+i] - coeff[1]) / coeff[2], 2.0)) + coeff[3] / (1.0 + pow((_id[_cwo[1]+i] - coeff[4]) / coeff[5], 2.0));'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Y(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a / (1.0 + pow((x_in-b)/c, 2.0)) + d / (1.0 + pow((y_in-f)/g, 2.0));\n"
        return s



class LorentzianB3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name ="Lorentzian B"
    _HTML = "z = a / (1+((x-b)/c)<sup>2</sup>) + d * (1+((y-f)/g)<sup>2</sup>)"
    coefficientDesignatorTuple = ("a", "b", "c", "d", "f", "g")
    function_cpp_code = 'temp = coeff[0] / (1.0 + pow((_id[_cwo[0]+i] - coeff[1]) / coeff[2], 2.0)) + coeff[3] / (1.0 + pow((_id[_cwo[1]+i] - coeff[4]) / coeff[5], 2.0));'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Y(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a / (1.0 + pow((x_in-b)/c, 2.0)) + d / (1.0 + pow((y_in-f)/g, 2.0));\n"
        return s



class LogNormalA3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name ="Log-Normal A"
    _HTML = "z = a * exp(-0.5 * (((ln(x)-b)/c)<sup>2</sup> + ((lny-d)/f)<sup>2</sup>))"
    coefficientDesignatorTuple = ("a", "b", "c", "d", 'f')
    CannotAcceptDataWithZeroX = True
    CannotAcceptDataWithNegativeX = True
    CannotAcceptDataWithZeroY = True
    CannotAcceptDataWithNegativeY = True
    function_cpp_code = 'temp = coeff[0] * exp(-0.5 * (pow((_id[_cwo[0]+i] - coeff[1]) / coeff[2], 2.0) + pow((_id[_cwo[1]+i] - coeff[3]) / coeff[4], 2.0)));'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_LogX(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_LogY(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a * exp(-0.5 * (pow((log(x_in)-b)/c, 2.0) + pow((log(y_in)-d)/g, 2.0)));\n"
        return s



class LogNormalB3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name ="Log-Normal B"
    _HTML = "z = a * exp(-0.5 * (((ln(x)-b)/c)<sup>2</sup>)) + d * exp(-0.5 * (((ln(y)-f)/g)<sup>2</sup>))"
    coefficientDesignatorTuple = ("a", "b", "c", "d", "f", "g")
    CannotAcceptDataWithZeroX = True
    CannotAcceptDataWithNegativeX = True
    CannotAcceptDataWithZeroY = True
    CannotAcceptDataWithNegativeY = True
    function_cpp_code = 'temp = coeff[0] * exp(-0.5 * (pow((_id[_cwo[0]+i] - coeff[1]) / coeff[2], 2.0))) + coeff[3] * exp(-0.5 * (pow((_id[_cwo[1]+i] - coeff[4]) / coeff[5], 2.0)));'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_LogX(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_LogY(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a * exp(-0.5 * (pow((log(x_in)-b)/c, 2.0))) + d * exp(-0.5 * (pow((log(y_in)-f)/g, 2.0)));\n"
        return s



class LogisticA3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name ="Logistic A"
    _HTML = "z = 4a * exp(-((x-b)/c))/((1+exp(-((x-b)/c)))<sup>2</sup>) + 4d * exp(-((y-f)/g))/((1+exp(-((y-f)/g)))<sup>2</sup>)"
    coefficientDesignatorTuple = ("a", "b", "c", "d", "f", "g")
    # reuse the existing C++ temp_x_sq and temp_y_sq variables.  A little touch of algebra is used for the negatives here
    function_cpp_code  = 'temp_x_sq = exp(-((_id[_cwo[0]+i] - coeff[1]) / coeff[2]));\n'
    function_cpp_code += 'temp_y_sq = exp(-((_id[_cwo[1]+i] - coeff[4]) / coeff[5]));\n'
    function_cpp_code += 'temp = 4.0 * coeff[0] * temp_x_sq / pow(1.0 + temp_x_sq, 2.0) + 4.0 * coeff[3] * temp_y_sq / pow(1.0 + temp_y_sq, 2.0);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Y(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = 4.0 * a * exp(-((x_in-b)/c)) / pow(1.0 + exp(-((x_in-b)/c)), 2.0) + 4.0 * d * exp(-((y_in-f)/g)) / pow(1.0 + exp(-((y_in-f)/g)), 2.0);\n"
        return s



class LogisticB3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name ="Logistic B"
    _HTML = "z = 16a * exp(-((x-b)/c)-((y-d)/f)) / ((1+exp(-((x-b)/c)))<sup>2</sup> * (1+exp(-((y-d)/f)))<sup>2</sup>)"
    coefficientDesignatorTuple = ("a", "b", "c", "d", 'f')
    # reuse the existing C++ temp_x_sq and temp_y_sq variables.  A little touch of algebra is used for the negatives here
    function_cpp_code  = 'temp_x_sq = -1.0 * ((_id[_cwo[0]+i] - coeff[1]) / coeff[2]);\n'
    function_cpp_code += 'temp_y_sq = -1.0 * ((_id[_cwo[1]+i] - coeff[3]) / coeff[4]);\n'
    function_cpp_code += 'temp = 16.0 * coeff[0] * exp((temp_x_sq + temp_y_sq)) / (pow(1.0 + exp(temp_x_sq), 2.0) * pow(1.0 + exp(temp_y_sq), 2.0));'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Y(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = 16.0 * a * exp(-((x_in-b)/c)-((y_in-d)/f)) / (pow(1.0 + exp(-((x_in-b)/c)), 2.0) * pow(1.0 + exp(-((y_in-d)/f)), 2.0));\n"
        return s



class ExtremeValueA3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name ="Extreme Value A"
    _HTML = "z = a * exp(-exp(-(x-b)/c)-(x-b)/c+1) + d * exp(-exp(-(y-f)/g)-(y-f)/g+1)"
    coefficientDesignatorTuple = ("a", "b", "c", "d", "f", "g")
    # reuse the existing C++ temp_x_sq and temp_y_sq variables.  A little touch of algebra is used for the negatives here
    function_cpp_code  = 'temp_x_sq = -1.0 * ((_id[_cwo[0]+i] - coeff[1]) / coeff[2]);\n'
    function_cpp_code += 'temp_y_sq = -1.0 + ((_id[_cwo[1]+i] - coeff[4]) / coeff[5]);\n'
    function_cpp_code += 'temp = coeff[0] * exp((-1.0 * exp(temp_x_sq)) - temp_x_sq + 1.0) + coeff[3] * exp((-1.0 * exp(temp_y_sq)) - temp_y_sq + 1.0);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Y(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a * exp(-exp(-(x_in-b)/c)-(x_in-b)/c+1.0) + d * exp(-exp(-(y_in-f)/g)-(y_in-f)/g+1.0);\n"
        return s



class ExtremeValueB3D(pythonequations.EquationBaseClasses.Equation3D):
    RequiresAutoGeneratedGrowthAndDecayForms = True
    RequiresAutoGeneratedOffsetForm = True
    RequiresAutoGeneratedReciprocalForm = False
    RequiresAutoGeneratedInverseForms = False
    _name ="Extreme Value B"
    _HTML = "z = a * exp(-exp(-(x-b)/c)-(x-b)/c+1) * exp(-exp(-(y-d)/f)-(y-d)/f+1)"
    coefficientDesignatorTuple = ("a", "b", "c", "d", 'f')
    # reuse the existing C++ temp_x_sq and temp_y_sq variables.  A little touch of algebra is used for the negatives here
    function_cpp_code  = 'temp_x_sq = -1.0 * ((_id[_cwo[0]+i] - coeff[1]) / coeff[2]);\n'
    function_cpp_code += 'temp_y_sq = -1.0 + ((_id[_cwo[1]+i] - coeff[3]) / coeff[4]);\n'
    function_cpp_code += 'temp = coeff[0] * exp((-1.0 * exp(temp_x_sq)) - temp_x_sq + 1.0) * exp((-1.0 * exp(temp_y_sq)) - temp_y_sq + 1.0);'


    def CreateCacheGenerationList(self):
        self.CacheGenerationList = []
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_X(NameOrValueFlag=1), []])
        self.CacheGenerationList.append([pythonequations.ExtraCodeForEquationBaseClasses.CG_Y(NameOrValueFlag=1), []])

    def SpecificCodeCPP(self):
        s = "\ttemp = a * exp(-exp(-(x_in-b)/c)-(x_in-b)/c+1.0) * exp(-exp(-(y_in-d)/f)-(y_in-d)/f+1.0);\n"
        return s
